﻿using System;
using System.Collections.Generic;
using AvantGameMachine.DataManagement;

namespace AvantGameMachine.Graphics
{
    public class RenderObject : IRenderizableObject
    {
        private PosVector[] vertexs = null;
        private int nv = 0;

        public RenderObject()
        {
        }

        public RenderObject PlaneBox(float _lenx, float _leny,float _posz,Texture _text)
        {
            return PlaneBox(_lenx,_leny,_posz,new Material(_text));
        }

        public RenderObject PlaneBox(float _lenx, float _leny, float _posz,Material _material)
        {
            Face face = this.CreateNew<Face>("face0");
            face.CreateBox(_lenx, _leny, _posz);
            face.FaceMaterial = _material;
            return this;
        }

        public RenderObject PlaneBox(float _lenx, float _leny, float _posz, Address _addr)
        {
            Texture t = new Texture(_addr);
            return PlaneBox(_lenx, _leny, _posz, t);
        }

        public RenderObject PlaneBoxToViewport(float _posz, Address _addr)
        {
            Texture t = new Texture(_addr);

            return PlaneBox(t.Size.Width, t.Size.Height, _posz, t);
        }

        public RenderObject PlaneBoxToViewport(Address _addr)
        {
            return PlaneBoxToViewport(0.0f, _addr);
        }

        public RenderObject PlaneBox(float _lenx, float _leny,float _posz)
        {
            return PlaneBox(_lenx, _leny, _posz, (Texture)null);
        }

        public RenderObject Box(float _lenx, float _leny, float _lenz)
        {
            Face face = new Face();
            face.CreateQuad(_lenx, _leny, _lenz);
            Transpolate(face, new PosVector(0.0f,0.0f,-_lenz), _lenz);
            return this;
        }

        public RenderObject Transpolate(Face _p, PosVector _axis, float _len)
        {
            vertexs = new PosVector[2 * _p.NumVertex]; // màxim num. vèrtexs

            nv = 0;
            int nf = 0;

            _axis.MakeUnit();
            _axis = new PosVector(_axis.X * _len, _axis.Y * _len, _axis.Z * _len);

            Face p2 = this.CreateNew<Face>("face" + nf);
            p2.SetNumVertex(_p.NumVertex);
            for (int i = 0; i < _p.NumVertex; i++)
            {
                PosVector v = new PosVector((_p.GetVertex(i).X + _axis.X), (_p.GetVertex(i).Y + _axis.Y), (_p.GetVertex(i).Z + _axis.Z));
                p2.SetVertex(i, v);
            }

            for (int i = 0; i < _p.NumVertex; i++)
            {
                nv++;
                vertexs[i] = _p.GetVertex(i);
                nv++;
                vertexs[i + _p.NumVertex] = p2.GetVertex(i);
            }

            nf++;
            Face f = this.CreateNew<Face>("face" + nf);
            f.SetNumVertex(_p.NumVertex);
            for (int j = 0; j < _p.NumVertex; j++)
            {
                f.addVertex(_p.GetVertex(j));
            }
            f.UpdateNormal();

            nf++;
            f = this.CreateNew<Face>("face" + nf);
            f.SetNumVertex(_p.NumVertex);
            for (int j = 0; j < _p.NumVertex; j++)
            {
                f.addVertex(p2.GetVertex(j));
            }
            f.UpdateNormal();

            for (int j = 0; j < _p.NumVertex; j++)
            {
                nf++;
                f = this.CreateNew<Face>("face" + nf);
                f.SetNumVertex(_p.NumVertex);
                int i1 = j + 1;
                int i2 = j;
                int i3 = j;
                int i4 = i3 + 1;

                if (i1 >= _p.NumVertex)
                    i1 = 0;

                if (i4 >= _p.NumVertex)
                    i4 = 0;

                f.addVertex(_p.GetVertex(i1));
                f.addVertex(_p.GetVertex(i2));
                f.addVertex(p2.GetVertex(i3));
                f.addVertex(p2.GetVertex(i4));
                f.UpdateNormal();
            }

            return this;
        }

        public override PosVector Max
        {
            get 
            {
                PosVector max = new PosVector(float.MinValue,float.MinValue,float.MinValue);

                for (int i = 0; i < children.Count; i++)
                {
                    PosVector temp = children.GetByIndex(i).Max;
                    if (temp.X > max.X)
                    {
                        max.X = temp.X;
                    }
                    if (temp.Y > max.Y)
                    {
                        max.Y = temp.Y;
                    }
                    if (temp.Z > max.Z)
                    {
                        max.Z = temp.Z;
                    }
                }
                return max;
            }
        }

        public override PosVector Min
        {
            get
            {
                PosVector min = new PosVector(float.MaxValue, float.MaxValue, float.MaxValue);

                for (int i = 0; i < children.Count; i++)
                {
                    PosVector temp = children.GetByIndex(i).Min;
                    if (temp.X < min.X)
                    {
                        min.X = temp.X;
                    }
                    if (temp.Y < min.Y)
                    {
                        min.Y = temp.Y;
                    }
                    if (temp.Z < min.Z)
                    {
                        min.Z = temp.Z;
                    }
                }
                return min;
            }
        }

        public int NumFaces
        {
            get { return NumChildren; }
        }

        public PosVector GetVertex(int _index)
        {
            return vertexs[_index];
        }

        public Face GetFace(int _index)
        {
            return GetChildByIndex<Face>(_index);
        }

    }
}
